package com.jwater.core.net;

import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * @description:
 * @author: jnner
 * @createDate: 2021/2/5
 * @version: 1.0
 */
public class CallUtils {
	protected static Logger logger = LoggerFactory.getLogger(CallUtils.class);

	// 异步调用返回结果的ThreadLocal变量
	private static ThreadLocal<AsyncResult> resultLocal = new ThreadLocal<AsyncResult>();
	// 超时时间的ThreadLocal变量
	private static ThreadLocal<Integer> timeoutLocal = new ThreadLocal<Integer>();

	/**
	 * 方法调用
	 * 
	 * @param <T>
	 * @param call
	 * @param timeout 设置方法调用的超时时间,单位是秒
	 * @return
	 * @throws Exception
	 */
	public static <T> T call(Callable<T> call, Integer timeout) throws Exception {
		timeoutLocal.set(timeout);
		return call.call();
	}

	protected static Integer getTimeoutFromLocal() {
		Integer timeout = timeoutLocal.get();
		timeoutLocal.remove();
		return timeout;
	}

	/**
	 * 异步调用
	 * 
	 * @param call   调用入口
	 * @param result 调用结果返回
	 */
	public static void asyncCall(Runnable call, AsyncResult result) {
		resultLocal.set(result);
		call.run();
	}

	protected static AsyncResult getAsyncResultFromLocal() {
		AsyncResult asyncResult = resultLocal.get();// 获取变量
		resultLocal.remove();// 删除变量
		return asyncResult;
	}

	/**
	 * 异步调用
	 * 
	 * @param call 调用入口
	 * @return 调用结果返回
	 */
	public static <T> Future<T> asyncCall(Runnable call) {
		final MyCall<T> myCall = new MyCall<T>();
		final FutureTask<T> futureTask = new FutureTask<T>(myCall);
		asyncCall(call, new AsyncResult() {
			@SuppressWarnings("unchecked")
			@Override
			public void onResult(Object obj) {
				myCall.setResultObj((T) obj);
				futureTask.run();
			}
		});
		return futureTask;
	}

	protected static class MyCall<T> implements Callable<T> {
		protected T resultObj;

		@Override
		public T call() throws Exception {
			return resultObj;
		}

		public void setResultObj(T resultObj) {
			this.resultObj = resultObj;
		}
	}
}
